home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / uk-sendmail2.1 / Chnbuild next >
Encoding:
Text File  |  1991-06-11  |  10.8 KB  |  508 lines

  1. #!/bin/sh
  2. #
  3. #  shell script to generate a sendmail chn-tbl.m4 file containing all
  4. #  the routing information for this host from a set of channel tables.
  5. #
  6. if [ $# -le 1 ]
  7. then    echo    "usage: $0 [-o outfile] -chn file..."
  8.     exit
  9. fi
  10.  
  11. #
  12. #  first, create the awk programs that compile the channel tables
  13. #
  14.  
  15. rm -f $$.*
  16. outf=chn-tbl.m4
  17.  
  18. #
  19. #  Standard format channel compiler
  20. #
  21. cat > $$.std.awk <<'EOF'
  22. NR==1    {
  23.     MINCLSIZE = 3
  24.     c = 1
  25.     mailer = substr(mailer, 2)
  26.     cl_outl = prefix "classl"
  27.     cl_outf = prefix "classf"
  28.     printf "\n# %s (%s channel)\n", file, mailer
  29.     }
  30.  
  31. NF==1    { $2 = substr($1, 1, index($1,".")-1) }        # shorthand
  32.  
  33. /%s/    {
  34.     # process wildcards
  35.     lhs = sprintf($1,"$+","$+","$+")
  36.     rhs = sprintf($1,"$2","$3","$4")
  37.     dest = sprintf($2,"$2","$3","$4")
  38.     printf "R$+@%s\t\t$@<$1@%s>%s.%s\n", lhs, rhs, dest, mailer >> S16
  39.     break
  40.     }
  41.  
  42.     {
  43.     i = index($1, ".")
  44.     subdom = substr($1,1,i-1)
  45.     restdom = substr($1,i+1)
  46.  
  47.     if (subdom == $2 && restdom != "")
  48.         link["$2/" restdom] = link["$2/" restdom] " " subdom
  49.     else
  50.         link[ $2 "/" restdom ] = link[ $2 "/" restdom ] " " subdom
  51.     }
  52.  
  53. END    {
  54.     for (i in link)
  55.     {    j = index(i,"/")
  56.         dest = substr(i, 1, j-1)
  57.         rdom = substr(i, j+1)
  58.         n = split(link[i], sub, " ")
  59.         if (n >= MINCLSIZE && c <= length(classes))
  60.         {    C = substr(classes, c, 1)
  61.             c++
  62.             printf "C%s%s\n", C , link[i]    >> cl_outf
  63.             printf "R$+@$=%s.%s\t\t$@<$1@$2.%s>%s.%s\n", \
  64.                 C, rdom, rdom, dest, mailer
  65.         }
  66.         else
  67.         {    host = dest
  68.             for (j=1; j<=n; j++)
  69.             {    if (dest == "$2") host = sub[j]
  70.                 printf "R$+@%s.%s\t\t$@<$1@%s.%s>%s.%s\n", \
  71.                     sub[j], rdom, sub[j], rdom, host, mailer
  72.             }
  73.         }
  74.     }
  75.  
  76.     print "" >>cl_outf
  77.     print substr(classes, c) > cl_outl
  78.     }
  79. EOF
  80.  
  81. #
  82. #   Janet channel compiler
  83. #
  84. cat > $$.janet.awk <<'EOF'
  85. NR==1    {
  86.     printf "\n# %s (Janet channel)\n", file
  87.     swap1 = sprintf("R$+@$+\t\t$:$>9$1@$2\t\tconvert to NRS style")
  88.     swap2 = sprintf("R$+@$+\t\t$:$>9$1@$2\t\tconvert back to 822 style")
  89.     }
  90.  
  91. NF==1    { $2 = $1 }        # shorthand
  92.  
  93. /%s/    {
  94.     if (wcnt++ == 0)  print swap1 >> S16
  95.  
  96.     # process wildcards
  97.     lhs = sprintf($1,"$+","$+","$+")
  98.     rhs = sprintf($1,"$2","$3","$4")
  99.     dest = sprintf($2,"$2","$3","$4")
  100.     if (rhs == dest)
  101.         jntaddr = "$1@" dest
  102.     else
  103.         jntaddr = "$1%" rhs "@" dest
  104.     printf "R$+@%s\t\t$@<%s>%s.janet\n", lhs, jntaddr, dest >> S16
  105.     break
  106.     }
  107.  
  108.     {
  109.     if (cnt++ == 0)  print swap1
  110.  
  111.     if ($1 == $2)
  112.         jntaddr = "$1@" $2
  113.     else
  114.         jntaddr = "$1%" $1 "@" $2
  115.     printf "R$+@%s\t\t$@<%s>%s.janet\n", $1, jntaddr, $2
  116.     }
  117.  
  118. END    {
  119.     if (cnt > 0) print swap2
  120.     if (wcnt > 0) print swap2 >> S16
  121.     }
  122. EOF
  123.  
  124. #
  125. #  UUCP channel compiler
  126. #
  127. cat > $$.uucp.awk <<'EOF'
  128. NR==1    {
  129.     MINCLSIZE = 3
  130.     c = 1
  131.     link[""]=""
  132.     cl_outl = prefix "classl"
  133.     cl_outf = prefix "classf"
  134.     printf "\n# %s (UUCP channel)\n", file
  135.     printf "R$+@$+\t\t\t$:$>8$1@$2\t\tconvert to uucp addresses\n"
  136.     }
  137.  
  138.     {
  139.     i = index($1, ".")
  140.     subdom = substr($1,1,i-1)
  141.     restdom = substr($1,i+1)
  142.     udest = subdom "!%s"
  143.  
  144.     if (NF == 1) $2 = udest        # shorthand
  145.  
  146.     if (udest == $2)
  147.         link[ "/" restdom ] = link[ "/" restdom ] " " subdom
  148.     else
  149.     {    pathl = length($2) - length(udest)
  150.         if ( substr($2, pathl) == ("!" udest) )
  151.         {    path = substr($2, 1, pathl-1)
  152.             link[ path "/" restdom ] = link[ path "/" restdom ] " " subdom
  153.         }
  154.         else
  155.         {    i = index($2, "!")
  156.             host = substr($2,1,i-1)
  157.             addr = sprintf( substr($2,i+1), "$1")
  158.             printf "R%s!$+\t\t$@<%s>%s.uucp\n", $1, addr, host
  159.         }
  160.     }
  161.     }
  162.  
  163. END    {
  164.     for (i in link)
  165.     {    j = index(i, "/")
  166.         path = substr(i, 1, j-1)
  167.         rdom = substr(i, j+1)
  168.         p = index(path, "!")
  169.         n = split(link[i], sub, " ")
  170.         if (n >= MINCLSIZE && c <= length(classes))
  171.         {    C = substr(classes, c, 1)
  172.             c++
  173.             printf "C%s%s\n", C, link[i]    >>cl_outf
  174.             if (path == "")
  175.             {    host = "$1"
  176.                 addr = ""
  177.             }
  178.             else if (p == 0)
  179.             {    host = path
  180.                 addr = "$1!"
  181.             }
  182.             else
  183.             {    host = substr(path,1,p-1)
  184.                 addr = substr(path,p+1) "!$1!"
  185.             }
  186.             printf "R$=%s.%s!$+\t\t$@<%s$2>%s.uucp\n", C, rdom, addr, host
  187.         }
  188.         else
  189.         {    for (j=1; j<=n; j++)
  190.             {    if (path == "")
  191.                 {    host = sub[j]
  192.                     addr = ""
  193.                 }
  194.                 else if (p == 0)
  195.                 {    host = path
  196.                     addr = sub[j] "!"
  197.                 }
  198.                 else
  199.                 {    host = substr(path,1,p-1)
  200.                     addr = substr(path,p+1) "!" sub[j] "!"
  201.                 }
  202.                 printf "R%s.%s!$+\t\t$@<%s$1>%s.uucp\n", \
  203.                         sub[j], rdom, addr, host
  204.             }
  205.         }
  206.     }
  207.     print "" >>cl_outf
  208.     print substr(classes, c) > cl_outl
  209.     print "\nR$+!$+\t\t\t$:$>7$1!$2\t\tconvert back to 822 style\n"
  210.     }
  211. EOF
  212.  
  213. #
  214. #  News channel compiler
  215. #
  216. cat > $$.news.awk << 'EOF'
  217. NR==1    { printf "\n# %s (news channel)\n", file }
  218.     {
  219.     lhs = sprintf($1,"$+","$+","$+")
  220.     rhs = sprintf($1,"$1","$2","$3")
  221.     dest = sprintf($2,"$1","$2","$3")
  222.  
  223.     if (NF == 1)
  224.         printf "R%s\t\t$@<%s>news\n", lhs, rhs
  225.     else
  226.         printf "R%s\t\t$@$>3 %s@%s\n", lhs, rhs, dest
  227.     }
  228. EOF
  229.  
  230.  
  231. #
  232. #  Top level domain relay compiler
  233. #
  234. cat > $$.top.awk <<'EOF'
  235. NR==1    {
  236.     MINCLSIZE = 3
  237.     c = 1
  238.     cl_outl = prefix "classl"
  239.     cl_outf = prefix "classf"
  240.     relay[""] = ""
  241.     }
  242. $1=="DEFAULT" || $1=="$=T"    { default = $2 ; break }
  243. $1=="ALL" || $1=="$+"        { all = $2 ; break }
  244.  
  245.     { relay[$2] = relay[$2] " " $1 }
  246.  
  247. END    {
  248.     for (i in relay)
  249.     {    n = split(relay[i], doms, " ")
  250.         if (n >= MINCLSIZE && c <= length(classes))
  251.         {    C = substr(classes, c, 1)
  252.             c++
  253.             printf "C%s%s\n", C, relay[i]    >> cl_outf
  254.             printf "R$+@$+.$=%s\t\t$@$>16$1%%$2.$3@%s\n", C, i
  255.         }
  256.         else
  257.         {    for (j=1; j<=n; j++)
  258.                 printf "R$+@$+.%s\t\t$@$>16$1%%$2.%s@%s\n", \
  259.                     doms[j], doms[j], i
  260.         }
  261.     }
  262.     if (default)    printf "R$+@$+.$=T\t\t$@$>16$1%%$2.$3@%s\n", default
  263.     if (all)    printf "R$+@$+\t\t$@$>16$1%%$2@%s\n", all
  264.  
  265.     print "" >>cl_outf
  266.     print substr(classes, c) > cl_outl
  267.     }
  268. EOF
  269.  
  270. #---------------------------------------
  271.  
  272. #
  273. #  awk scripts for compiling to ida databases
  274. #
  275. cat > $$.std.ida.awk <<'EOF'
  276. NR==1    {
  277.     mailer = substr(mailer, 2)
  278.     printf "\n# %s (%s channel)\n", file, mailer
  279.     printf "R$+@$+\t\t$:$(%s $2 $@ $1 $: $1@$2 $)\t\tlookup database\n",key
  280.     printf "R<$+>$+.%s\t\t$@<$1>$2.%s\t\tfound a match\n", mailer,mailer
  281.     }
  282. NF==1    { $2 = substr($1, 1, index($1,".")-1) }        # shorthand
  283.     { printf "%s\t<%%s@%s>%s.%s\n", $1, $1, $2, mailer > dbmf }
  284. EOF
  285.  
  286. cat > $$.janet.ida.awk <<'EOF'
  287. NR==1   {
  288.     printf "\n# %s (Janet channel)\n", file
  289.     printf "R$+@$+\t\t$:$>9$1@$2\t\tconvert to NRS style\n"
  290.     printf "R$+@$+\t\t$:$(%s $2 $@ $1 $: $1@$2 $)\t\tlookup database\n",key
  291.     printf "R<$+>$+.janet\t\t$@<$1>$2.janet\t\tfound a match\n"
  292.     }
  293. NF==1    { $2 = $1 }        # shorthand
  294.     {
  295.     if ($1 == $2)
  296.         jntaddr = "%s@" $2
  297.     else
  298.         jntaddr = "%s%%" $1 "@" $2
  299.  
  300.     printf "%s\t<%s>%s.janet\n", $1, jntaddr, $2 > dbmf
  301.     }
  302. END     { printf "\nR$+@$+\t\t$:$>9$1@$2\t\tconvert back to 822 style\n" }
  303. EOF
  304.  
  305.  
  306. #---------------------------------------
  307.  
  308. #
  309. #  compile the tables; output goes into various files
  310. #
  311.  
  312. strip="sed -e /#/s/#.*// -e /^\$/d"
  313. classes="NOPQRSUVWXYZ"
  314. dbkeys="BCDEFHIJ"
  315. cp /dev/null $$.classf
  316.  
  317. while [ $# -gt 0 ]
  318. do
  319.     case $1 in
  320.  
  321.     -o)    outf=$2
  322.         ;;
  323.  
  324.     -local)    $strip -e 's/^LHOST\./$=w./' $2 | awk '
  325.         { printf "R$+@%s\t\t$@$1@$J\n", $1       >> S15
  326.           printf "R$+@%s\t\t$@<$1@$J>error\n", $1  >> S17
  327.         }'  S15=$$.S15  S17=$$.S17 -
  328.         ;;
  329.  
  330.     -ether|-tcp|-csnet|-decnet|-xerox)
  331.         $strip $2 | awk -f $$.std.awk mailer=$1 file=$2 prefix=$$. \
  332.                 classes=$classes S16=$$.S16 - >> $$.S17
  333.         classes=`cat $$.classl`
  334.         ;;
  335.  
  336.     -janet)    $strip $2 | awk -f $$.janet.awk file=$2 S16=$$.S16 - >> $$.S17
  337.         ;;
  338.  
  339.     -uucp)    $strip $2 | awk -f $$.uucp.awk file=$2 prefix=$$. \
  340.                 classes=$classes - >> $$.S17
  341.         classes=`cat $$.classl`
  342.         ;;
  343.  
  344.     -news)    $strip $2 | awk -f $$.news.awk file=$2 - >> $$.S18
  345.         ;;
  346.  
  347.     -top)    $strip $2 | awk -f $$.top.awk prefix=$$. \
  348.                 classes=$classes - >> $$.S16
  349.         classes=`cat $$.classl`
  350.         ;;
  351.  
  352.     -ida)    shift
  353.         key=`expr substr $dbkeys 1 1`
  354.         dbkeys=`expr substr $dbkeys 2 26`
  355.         dbmfile=`basename $2 .chn`
  356.  
  357.         case $1 in
  358.         -janet)    $strip $2 | awk -f $$.janet.ida.awk file=$2 \
  359.                 key=$key dbmf=$dbmfile.ida - >> $$.S17
  360.             ;;
  361.  
  362.         *)    $strip $2 | awk -f $$.std.ida.awk mailer=$1 file=$2 \
  363.                 key=$key dbmf=$dbmfile.ida - >> $$.S17
  364.             ;;
  365.         esac
  366.  
  367.         dbm load $dbmfile.ida $dbmfile
  368.         echo "OK$key`pwd`/$dbmfile" >> $$.S17
  369.         rm $dbmfile.ida
  370.         ;;
  371.  
  372.     *)    echo "usage: $0 [-o file] -chn file..."
  373.         rm -f $$.*
  374.         exit 1
  375.         ;;
  376.     esac
  377.     shift
  378.     shift
  379. done
  380.  
  381. #---------------------------------------
  382.  
  383. #
  384. #  now glue all the bits together
  385. #
  386.  
  387. #
  388. #  The header
  389. #
  390. cat > $outf <<EOF
  391. ###############################################################################
  392. #####
  393. #####    @(#)$outf    UK-2.1 sendmail configuration        18/11/88
  394. #####
  395. #####    The mailer selection and routing
  396. #####
  397. ###############################################################################
  398.  
  399. # classes
  400. EOF
  401.  
  402. #
  403. #  the classes
  404. #
  405. while read class group
  406. do
  407.     echo "$group" | fmt | sed "s/^/$class/"
  408. done < $$.classf >> $outf
  409.  
  410. #
  411. #  the rules
  412. #
  413. cat - $$.S15 >> $outf <<'EOF'
  414.  
  415. ###########################################
  416. #  Ruleset 15  --  local domain handling  #
  417. ###########################################
  418.  
  419. #
  420. #  This rule converts various forms of local domain names
  421. #  into the standard ($J) name
  422. #
  423.  
  424. S15
  425. ifdef(`MULTIHOST',
  426. `R$+@$=w.$J        $@$1@$J            host specific name')
  427. EOF
  428.  
  429. cat - $$.S16 >> $outf <<'EOF'
  430.  
  431. #############################
  432. #  Ruleset 16  --  routing  #
  433. #############################
  434.  
  435. #
  436. #  This rule trys to find an "<address>host.network" triple for a given
  437. #  domain address.  Given a domain address "u@a.b.c.d", it calls the
  438. #  channel matcher with u@a.b.c.d, and if nothing matched, it calls
  439. #  the channel matcher again, with "u%a.b.c.d@b.c.d" and  "u%a.b.c.d@c.d".
  440. #  If there's still no match, then the top level domain relaying is done
  441. #  e.g. "u%a.b.c.d@d" -> "u%a.b.c.d@x.y.z" and the rule is retried.
  442. #
  443.  
  444. S16
  445. R$+@$+            $:$>17$1@$2        initial routing
  446. R<$+>$+            $@<$1>$2        success, return triple
  447.  
  448. #  initial match failed, retry with successively higher level domains
  449. R<$+@$+>        $:<$1%$2@$2>        u@a.b.c -> u%a.b.c@a.b.c
  450. R<$+@$-.$+>        $>17$1@$3        retry routing
  451. R<$+>$+            $@<$1>$2        success, return triple
  452.  
  453. #  match failed, attempt to match with "general" rules (wildcards);
  454. #  if this fails then try matching top level domain to find relay domain
  455. R<$+@$->        $:$>4$1            restore original address
  456.  
  457. EOF
  458.  
  459. cat - $$.S17 >> $outf <<'EOF'
  460.  
  461. ######################################
  462. #  Ruleset 17  --  channel matching  #
  463. ######################################
  464.  
  465. #
  466. #  This rule takes a full domain address and trys to match it with a
  467. #  domain given on the LHS of a rule.
  468. #  If one matches, the "<address>host.network" triple given on the RHS
  469. #  is returned.  Else  "<address>" is returned.
  470. #
  471.  
  472. S17
  473. R$+@$J            $@<$1@$J>error        unknown local subdomain error
  474. EOF
  475.  
  476. #
  477. #  complete ruleset 17
  478. #
  479. cat >> $outf <<'EOF'
  480.  
  481. R$+            $@<$1>            no match, return "<address>"
  482. EOF
  483.  
  484. if [ -f $$.S18 ]
  485. then    cat - $$.S18 >> $outf <<'EOF'
  486.  
  487. #############################################
  488. #  Ruleset 18  --  newsgroup name matching  #
  489. #############################################
  490.  
  491. #
  492. #  This rule takes a local address and trys to match it with a
  493. #  newsgroup name given on the LHS of a rule.
  494. #  If one matches, the "<name>news" double given on the RHS
  495. #  is returned. If a relayed newsgroup is found, ruleset 3 is
  496. #  re-entered with name@relay. Else  "address" is returned.
  497. #
  498.  
  499. S18
  500. # send non-local addresses straight back
  501. R$+@$+              $@$1@$2             not a local address
  502.  
  503. EOF
  504. fi
  505.  
  506. rm -f $$.*
  507. exit
  508.